<template>
  <div :class="['preview-content']">
    <div
      class="preview-box"
      v-for="(item, index) in list"
      :key="index"
      @mouseenter="moveEnter(index)"
      @mouseleave="moveLeave"
    >
      <HProgress :status="item.status" />
      <div class="prview-del" title="删除" @click="handleRemove(item)" v-if="showDel(item)">
        <CloseOutlined
      /></div>
      <img
        class="preview-icon"
        :src="item.prevUrl"
        alt="缩略图"
        width="100%"
        v-if="showIcn(item)"
      />
      <div class="preview-filename" :title="item[labelField]" v-if="showFileName(item)">{{
        item[labelField]
      }}</div>

      <div
        class="preview-links"
        :style="{ top: flagIndex == index ? styleTop : '100%' }"
        v-if="showIcn(item)"
      >
        <EyeOutlined
          title="预览"
          v-if="isPreview"
          :style="{ fontSize: '20px', color: '#d9d9d9', cursor: 'pointer' }"
          @click="handleTap('prev', index)"
        />
        <DownloadOutlined
          title="下载"
          @click="handleTap('download', index)"
          v-if="isDownload"
          :style="{ fontSize: '20px', color: '#d9d9d9', cursor: 'pointer', marginLeft: '10px' }"
        />
      </div>
    </div>
    <div
      class="preview-box"
      style="display: flex; align-items: center; justify-content: center"
      v-if="showLoadImg"
    >
      <img :src="loadImg" :width="30" :preview="false"
    /></div>
    <slot></slot>
  </div>
  <PreviewModal
    :isDownload="isDownload"
    @register="registerModal"
    :valueField="valueField"
    :downloadField="downloadField"
    @download-file="downloadFn"
    @preview-file="previewFn"
  />
</template>

<script setup lang="ts">
  import HProgress from './Hprogress.vue';
  import { CloseOutlined, EyeOutlined, DownloadOutlined } from '@ant-design/icons-vue';
  import { ref, computed, unref } from 'vue';
  import { useModal } from '/@/components/Modal';
  import { checkFileType } from '../../hooks/uploadCheck';
  import word from '/@/assets/images/word.png';
  import pdf from '/@/assets/images/pdf.png';
  import other from '/@/assets/images/other.png';
  import PreviewModal from './previewModal.vue';
  import { createImgPreview } from '/@/components/Preview/index';
  import { isArray } from '/@/utils/is';
  import { StatusText } from '../props';

  import loadImg from '/@/assets/images/load-img.png';

  interface FileItem {
    url: string;
    id?: string;
    fileName?: string;
    prevUrl?: string;
    _type?: string;
    _file: File;
    status?: StatusText;
    percent?: number;
  }

  const styleTop = ref<string>('100%');

  const flagIndex = ref<number>(-1);

  const props = defineProps({
    maxNumber: {
      type: Number,
      default: 1,
    },
    // 文件后缀
    suffixField: {
      type: String,
      default: 'fileName',
    },
    valueField: {
      type: String,
      default: 'value',
    },
    labelField: {
      type: String,
      default: 'value',
    },
    downloadField: {
      type: String,
      default: 'url',
    },
    previewList: {
      type: Array as PropType<FileItem[]>,
      default: () => [],
    },
    isPreview: {
      type: Boolean,
      default: true,
    },
    isDownload: {
      type: Boolean,
      default: true,
    },
    disabled: {
      type: Boolean,
      default: true,
    },
    showFileName: {
      type: Boolean,
      default: true,
    },
    //  是否拖拽
    dragger: {
      type: Boolean,
      default: true,
    },
  });

  const emits = defineEmits(['remove']);

  const [registerModal, { openModal }] = useModal();

  const wordList: string[] = ['.doc', '.docx', '.ppt', '.pptx', '.xlsx', '.xls', '.txt'];
  const imgList: string[] = ['.bmp', '.jpg', '.jpeg', '.png', '.gif', '.svg', '.psd'];

  const list = computed(() => {
    if (!isArray(props.previewList)) return [];
    return props.previewList.map((i: FileItem) => {
      let type = checkFileType(i[props.valueField], '', true);
      if (!type) {
        type = checkFileType(i[props.suffixField], '', true);
      }
      switch (true) {
        case type === '.pdf':
          i.prevUrl = pdf;
          i._type = 'pdf';
          break;
        case wordList.includes(type as string): //word
          i.prevUrl = word;
          i._type = 'word';
          break;
        case imgList.includes(type as string): //图片
          i.prevUrl = i[props.valueField];
          i._type = 'image';
          break;
        default: //其他类型
          i.prevUrl = other;
          i._type = 'other';
      }
      return i;
    });
  });
  const showLoadImg = computed(() => unref(list).length < props.maxNumber && !props.dragger);

  const handleRemove = (item) => {
    emits('remove', item);
  };

  let downFile: Fn;
  let previewFile: Fn;

  const downloadFn = (val) => {
    downFile = val;
  };

  let previewFn = (val) => {
    previewFile = val;
  };

  const handleTap = (str: string, index: number) => {
    if (str == 'download') {
      if (list.value[index]._type === 'image') {
        window.open(list.value[index][props.valueField], '_self');
        return;
      }
      downFile(list.value[index]);
      return;
    } else {
      if (list.value[index]._type === 'image') {
        createImgPreview({
          imageList: [list.value[index][props.valueField]],
          defaultWidth: 700,
          rememberState: true,
        });
        return;
      }
      previewFile(list.value[index]);
    }
    openModal(true);
  };

  const moveEnter = (index) => {
    styleTop.value = '0';
    flagIndex.value = index;
  };

  const moveLeave = () => {
    styleTop.value = '100%';
    flagIndex.value = -1;
  };

  const showIcn = (item: FileItem) => {
    if (!item.status || ['done'].includes(item.status)) {
      return true;
    }
    return false;
  };

  const showDel = (item: FileItem) => {
    if ((!item.status || ['error', 'done'].includes(item.status)) && !props.disabled) {
      return true;
    }

    return false;
  };

  const showFileName = (item: FileItem) => {
    if ((!item.status || ['done'].includes(item.status)) && props.showFileName) {
      return true;
    }

    return false;
  };
</script>

<style lang="less" scoped>
  .preview-content {
    display: flex;
    flex-wrap: wrap;
    width: 100%;

    .preview-box {
      position: relative;
      width: 80px;
      height: 80px;
      border: 1px solid #f5f5f5;
      padding: 8px;
      background: #fff;
      margin-right: 10px;
      margin-bottom: 10px;
      overflow: hidden;
      border-radius: 4px;
      pointer-events: auto;
      cursor: auto;

      &:hover {
        transition: all 1s ease;
      }

      .prview-del {
        width: 30px;
        height: 30px;
        background: rgba(0, 0, 0, 0.5);
        position: absolute;
        right: -10px;
        top: -10px;
        border-radius: 50%;
        padding-top: 8px;
        padding-left: 5px;
        color: #fff;
        cursor: pointer;
        z-index: 10;
      }

      .preview-links {
        position: absolute;
        top: 100%;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.6);
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .preview-icon {
        width: 100%;
        height: 100%;

        :deep(.ant-image-img) {
          width: 100%;
          height: 100%;
        }

        :deep(.ant-progress-text) {
          margin: 0;
        }
      }

      .preview-filename {
        position: absolute;
        width: 100%;
        bottom: 0;
        left: 0;
        background: rgba(0, 0, 0, 0.6);
        color: #d9d9d9;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        cursor: pointer;
        z-index: 10;
      }
    }
  }
</style>
